#include "sysmonitor/utils.hpp"
#include <sstream>
#include <algorithm>
#include <cctype>
#include <cmath>
#include <iostream>

namespace sysmonitor {
namespace utils {

double UnitConverter::convertBytes(uint64_t bytes, Unit targetUnit) {
    double value = static_cast<double>(bytes);
    switch (targetUnit) {
        case Unit::B:  return value;
        case Unit::KB: return value / 1024.0;
        case Unit::MB: return value / (1024.0 * 1024.0);
        case Unit::GB: return value / (1024.0 * 1024.0 * 1024.0);
        case Unit::TB: return value / (1024.0 * 1024.0 * 1024.0 * 1024.0);
        default: return value;
    }
}


std::pair<double, UnitConverter::Unit> UnitConverter::autoConvertBytes(uint64_t bytes) {
    if (bytes >= 1024ULL * 1024ULL * 1024ULL * 1024ULL) {
        return {convertBytes(bytes, Unit::TB), Unit::TB};
    } else if (bytes >= 1024ULL * 1024ULL * 1024ULL) {
        return {convertBytes(bytes, Unit::GB), Unit::GB};
    } else if (bytes >= 1024ULL * 1024ULL) {
        return {convertBytes(bytes, Unit::MB), Unit::MB};
    } else if (bytes >= 1024ULL) {
        return {convertBytes(bytes, Unit::KB), Unit::KB};
    } else {
        return {static_cast<double>(bytes), Unit::B};
    }
}


std::string UnitConverter::unitToString(Unit unit) {
    switch (unit) {
        case Unit::B:  return "B";
        case Unit::KB: return "KB";
        case Unit::MB: return "MB";
        case Unit::GB: return "GB";
        case Unit::TB: return "TB";
        default: return "B";
    }
}


std::string UnitConverter::formatBytes(uint64_t bytes) {
    auto [value, unit] = autoConvertBytes(bytes);
    std::stringstream ss;
    ss.precision(2);
    ss << std::fixed << value << " " << unitToString(unit);
    return ss.str();
}


namespace string {

std::string trim(const std::string& str) {
    const char* whitespace = " \t\n\r\f\v";
    size_t first = str.find_first_not_of(whitespace);
    if (first == std::string::npos) {
        return ""; // 字符串全是空白
    }
    size_t last = str.find_last_not_of(whitespace);
    return str.substr(first, (last - first + 1));
}


std::vector<std::string> split(const std::string& str, char delimiter) {
    std::vector<std::string> tokens;
    std::string token;
    std::istringstream tokenStream(str);
    while (std::getline(tokenStream, token, delimiter)) {
        if (!token.empty()) {
            tokens.push_back(token);
        }
    }
    return tokens;
}


bool stringToULongLong(const std::string& str, uint64_t& result) {
    try {
        size_t pos;
        result = std::stoull(str, &pos);
        // 确保整个字符串都被转换了
        return pos == str.size();
    } catch (...) {
        return false;
    }
}

} // namespace string
} // namespace utils
} // namespace sysmonitor
